package com.only4play.interceptor;

import com.only4play.common.constants.ErrorCodeEnum;
import com.only4play.common.exception.ApplicationException;
import com.only4play.config.NoAuthUriConfiguration;
import com.only4play.jwt.JwtCodec;
import com.only4play.jwt.JwtConfig;
import com.only4play.jwt.JwtPayload;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * @author liyuncong
 * @version 1.0
 * @file JwtAuthInterceptor
 * @brief token认证拦截器
 * @details token认证拦截器
 * @date 2024-02-21
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2024-02-21               liyuncong          Created
 */

@Slf4j
public class JwtAuthInterceptor implements HandlerInterceptor {

    private static final String ACCESS_TOKEN_HEADER = "auth_access_token";

    @Autowired
    private NoAuthUriConfiguration noAuthUriConfiguration;
    @Autowired
    private JwtCodec<?> jwtCodec;
    @Autowired
    private JwtConfig jwtConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String uri = request.getRequestURI();
        // 匹配不用登录验证的URI
        if (noAuthUriConfiguration.getNoAuthUri().stream().anyMatch(uri::contains)) {
            log.info("current uri skip auth, uri={}", uri);
            return true;
        }

        // 进行统一认证拦截
        String token = request.getHeader(ACCESS_TOKEN_HEADER);
        if (!StringUtils.hasText(token)) {
            throw new ApplicationException(ErrorCodeEnum.UNAUTHORIZED);
        }
        // 验证token
        boolean verify = jwtCodec.verify(token, jwtConfig);
        if (!verify) {
            throw new ApplicationException(ErrorCodeEnum.UNAUTHORIZED);
        }

        return true;
    }
}
